SVG动画从入门到实战,提升你的网站表现力

您所在的位置:网站首页 svg hover变色 SVG动画从入门到实战,提升你的网站表现力

SVG动画从入门到实战,提升你的网站表现力

2024-02-04 23:27| 来源: 网络整理| 查看: 265

在 SVG 中,如果我们想实现一个动画效果,可以使用 CSS,JS,或者直接使用 SVG 中自带的 animate 元素(SMIL)。

这里我们主要探讨SVG与CSS结合实现的一些常见动画效果。

(下面要使用到的SVG基础知识,在 SVG从入门到图标绘制和组件封装 和 SVG中的Transform详解---平移、旋转和缩放 中都有详细的介绍,这里就不重复了,有需要的朋友可以前往查看哦。 )

SVG + CSS 动画实现的基础

HTML5 支持内联 SVG,我们可以将SVG元素作为html标签的一种,直接在页面结构中使用,成为 DOM 的一部分,这也使得我们可以用 CSS 对其做样式开发,这也是SVG + CSS 动画实现的基础。

上面的代码片段在页面绘制一个宽高100px的金色正方形。这里使用标签属性的方式描述它的宽度、高度和填充色,其实我们也可以在CSS中写这些样式。

rect{ width: 100px; height: 100px; fill: gold; }

既然能用CSS对SVG做样式开发,那么结合animation、transition、transform,使SVG元素的样式进行动态变换,就可以达到我们想要的动画效果。

rect{ width: 100px; height: 100px; fill: gold; transition: fill 1s linear; } rect:hover{ fill: greenyellow; }

hover-color-change.gif

基于transform的形状变换动画

和普通的HTML元素一样,SVG元素可以通过transform进行平移、旋转和缩放等形状变换。

但两者的变换参考点不同。对于普通的HTML元素,变换的参考点,默认值是元素自身在x、y方向的中心位置50% 50%(这里仅考虑二维平面),也就是元素的旋转、移位、缩放等操作都是以元素自身在x、y方向的中心位置进行的。

而SVG元素,变换的参考点,是在SVG画布的0 0的位置(默认是元素的左上角)。

image.png

理解这一点对于理解SVG元素的transform变换非常重要,我们在前面的两篇文章中进行了非常详尽的讲解:

SVG从入门到图标绘制和组件封装

SVG中的Transform详解---平移、旋转和缩放

仿B站直播图标 动画实现

使用标签绘制三条竖直的线条,(x1,y1)是线条起始点的坐标,(x2,y2)是线条终点的坐标。

image.png

(为了方便观察,我们给svg设置一个蓝色边框。)

接着,通过keyframes动画,不断改变scaleY,让线条在Y方向进行缩放。

.beat{ transform-origin: bottom; //将变换参考点设置成`元素`的底部 animation: beat-scale 1.4s linear infinite; } @keyframes beat-scale{ 25%{ transform: scaleY(0.3); } 50%{ transform: scaleY(1); } 75%{ transform: scaleY(0.3); } }

beat-0.gif

最后,通过设置animation-delay,让三段线条交错运动。

.beat:nth-child(1){ animation-delay: 0.4s; } .beat:nth-child(2){ animation-delay: 0.2s; }

beat-11.gif

组件封装

实现了动画,接下来就是把图标进行组件封装,以便一次定义,多处引用。

参考:SVG组件封装

两个改造点:

1、将标签都放到中,标签设置viewBox="0 0 100 100"; 2、将stroke="lightblue"改成stroke="currentColor",在使用svg图标时,颜色就会从父元素的color属性继承。

使用:

直播中

beat-3.gif

加载时钟

标签绘制时钟轮廓,两个绘制长针和短针。

image.png

长短针的旋转,我们希望绕图标自身中心点进行。

我们知道,SVG元素变换的参考点,是在SVG画布的0 0的位置。那么如果图标的中心点与SVG画布0 0的位置重叠,那图标岂不就绕自身中心点进行旋转。

因此,我们将标签圆心坐标设为(0,0)(cx="0" cy="0"),同时长短针的起点坐标也设为(0,0)。为了图形显示完全,设置元素的viewBox属性为"-52 -52 104 104"

image.png

动画的实现就是通过keyframes动画,不断改变长短针的rotate角度,由于两者旋转速度不同,所以动画时间设置不同。

.fast-hand{ animation: clock-rotate 2s linear infinite; /*动画时间设置不同*/ } .slow-hand{ animation: clock-rotate 15s linear infinite; /*动画时间设置不同*/ } @keyframes clock-rotate{ 0%{ transform: rotate(0deg); } 100%{ transform: rotate(360deg); } }

clock-1.gif

封装成组件的代码和使用案例如下:

等待中

clock-2.gif

描边动画

常用 SVG + CSS 来实现的,除了transform + animation/transition这种组合实现图标的形状变换动画,另一种用处非常广泛的就是描边动画。

stroke-dasharray & stroke-dashoffset

描边动画的核心是 SVG 的两个显示属性,分别是 stroke-dasharray和stroke-dashoffset。

stroke-dasharray用于创建虚线。它的值是一个序列,可以传入多个值,分别指定虚线中线段和间隔的长度。

stroke-dasharray = '10, 20' 表示:线段10,间距20,然后重复 线段10,间距20。。。

该参数序列可以是一到多个数值,当数值的个数为奇数时,会自动复制一份,再生效。

比如stroke-dasharray = '10'相当于stroke-dasharray = '10, 10';

stroke-dasharray = '10, 20, 30'相当于stroke-dasharray = '10, 20, 30, 10, 20, 30',此时的绘制规则是:线段10,间距20,线段30,间距10,线段20,间距30,然后重复。。。

image.png stroke-dashoffset: 描述相对于起始点的偏移。它的值是一个数值X,X>0时,相当于往左移动了X个长度单位; X0,线段就会逐渐显示出来。从而产生描边的效果。

offset3.gif

描边效果的动画在开发中有很多应用场景,比如各种形状的进度条,图标或文字的描边,以及一些酷炫的按钮边框动画等。

案例实现 环形进度条

首先,我们将stroke-dasharray和stroke-dashoffset都设为圆环的周长;然后根据进度progress计算动态计算出新的stroke-dashoffset,即(1-progress) * 圆环的周长。

circle-progress.gif

计算圆环周长的方法:

1、在已知半径的情况下,可以根据公式2*Pi*r求得周长。 2、SVG的形状元素都有一个getTotalLength的方法,可以获取该形状的路径总长度,对于规则和不规则的形状都适用。 //页面结构 调整进度: //js代码,获取圆环周长,并在调整进度后改变蓝色圆环的stroke-dashoffset const progressDom = document.querySelector('.progress') const percent = progressDom.dataset.percent const circleDom = document.querySelector('.process-circle') //通过getTotalLength方法获取圆环周长 const circleLen = circleDom.getTotalLength() console.log(circleLen) circleDom.style.strokeDashoffset = circleLen * ( 1 - parseInt(percent) / 100 ) //监听进度改变的事件,实际开发中的数据可能通过ajax获取 document.querySelector('#range').addEventListener('change', (e) => { circleDom.style.strokeDashoffset = circleLen * ( 1 - parseInt(e.target.value) / 100 ) progressDom.dataset.percent = e.target.value + '%' }) //css代码 .progress{ display: inline-block; position: relative; } .progress::before{ content: attr(data-percent); position: absolute; width: 100%; top: 50%; left: 0; transform: translateY(-50%); font-size: 20px; text-align: center; } .progress::after{ content: attr(data-name); position: absolute; width: 100%; top: 100%; left: 0; font-size: 25px; text-align: center; } .process-circle{ stroke-dashoffset:251; transition: stroke-dashoffset 3s; } .adjust{ margin-top: 50px; } 环形加载动画

stroke-dashoffset和animation结合还可以实现环形的加载动画,这是一种非常常见的加载动画。 circle-loading1.gif

.progress{ stroke: #F7C223; animation: move 2s linear infinite; } .container{ animation: container 2s linear infinite; } //给外框也加上旋转动画,两个旋转叠加,效果更自然 @keyframes container { 0% { transform: rotate(0deg); } 100% { transform: rotate(270deg); } } @keyframes move{ //在改变stroke-dashoffset的同时也让圆环旋转 0%{ stroke-dashoffset: 251px; } 50%{ stroke-dashoffset: calc(251px * 0.2); transform:rotate(135deg); } 100%{ stroke-dashoffset: 251px; transform:rotate(450deg); } }

还可以再加上变色的动画,效果更绚丽。

circle-loading3.gif

.progress{ stroke: #F7C223; animation: move 2s linear infinite, color-change 2s linear infinite; } @keyframes color-change { 0% { stroke: #4285F4; } 25% { stroke: #DE3E35; } 50% { stroke: #F7C223; } 75% { stroke: #1B9A59; } 100% { stroke: #4285F4; } } 文字描边

以描边动画的方式出场可以使人对logo或者文字的印象更加深刻。

text-miaobian.gif

这里每个字母都是由path元素绘制的图标,这种比较复杂的图形一般是由设计软件绘制,然后生成svg代码,我们这里使用的是figma。

对于这种不规则图形,只能用getTotalLength方法可以获取该形状的路径总长度,然后设置stroke-dasharray和stroke-dashoffset的值。

const words = document.querySelectorAll('path') for(let i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3